#include "protocol.hpp"
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <string>
#include <stdlib.h>

namespace Ser
{
    class Server
    {
    private:
        int listen_sock;
        uint16_t port;
    public:
        Server(uint16_t _port):port(_port),listen_sock(-1){}
        ~Server()
        {
            if(listen_sock>=0) close(listen_sock);
        }
        void InitServer()
        {
            //1.创建套接字文件
            int listen_sock=socket(AF_INET,SOCK_STREAM,0);//ipv4-流式套接-默认协议
            if(listen_sock < 0)
            {
                std::cerr<<"socket error"<<std::endl;
                exit(1);
            }
            //2.填写ip和port及绑定
            struct sockaddr_in local;
            socklen_t len=sizeof(local);
            bzero(&local,len);
            local.sin_family=AF_INET;
            local.sin_port=htons(port);
            local.sin_addr.s_addr=htons(INADDR_ANY);//云服务器的绑定
            if(bind(listen_sock,(struct sockaddr*)&local,len)<0)
            {
                std::cerr<<"bind error"<<std::endl;
                exit(2);
            }
            //3.设置listen监听状态
            if(listen(listen_sock,5)<0)
            {
                std::cerr<<"listen error"<<std::endl;
                exit(3);
            }
        }
        static void* Routine(void* args)
        {
            pthread_detach(pthread_self());//线程分离
            int sock=(*(int*)args);
            delete (int*)args;
            //执行处理逻辑
            while (true)
            {
                ns_protocol::Request req;
                ssize_t s=recv(sock,&req,sizeof(req),0);
                if(s>0)
                {
                    ns_protocol::Response resp;
                    switch (req.op)
                    {
                    case '+':
                        resp.result=req.x+req.y;
                        break;
                    case '-':
                        resp.result=req.x-req.y;
                        break;
                    case '*':
                        resp.result=req.x*req.y;
                        break;
                    case '/':
                        if(req.y!=0)
                            resp.result=req.x/req.y;
                        else
                            resp.code=1;
                        break;
                    case '%':
                        if(req.y!=0)
                            resp.result=req.x%req.y;
                        else
                            resp.code=2;
                        break;
                    default:
                        resp.code=3;
                        break;
                    }
                    send(sock,&resp,sizeof(resp),0);
                }
                else if(s==0)
                {
                    std::cout<<"client quit..."<<std::endl;
                    break;
                }
                else
                    break;
            }
            close(sock);
            return nullptr;
        } 
        void Loop()
        {
            while(true)
            {
                struct sockaddr_in peer;
                socklen_t len=sizeof(peer);
                bzero(&peer,len);
                //4.建立链接
                int sock=accept(listen_sock,(struct sockaddr*)&peer,&len);
                if(sock < 0)
                {
                    std::cerr<<"accept"<<std::endl;
                    continue;
                }
                int* p=new int(sock);
                pthread_t tid;
                pthread_create(&tid,nullptr,Routine,p);
    
            }
        }
    };
}